package io.gitee.kotle.android.mvvm

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.gitee.kotle.android.utils.StatusData
import io.gitee.kotle.android.utils.runWithStatus
import io.gitee.kotle.android.utils.toast
import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

abstract class MvvmViewModel : ViewModel() {

    inline fun <T> MutableLiveData<StatusData<T>>.runOnScope(
        toastError: Boolean = true,
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        crossinline errorBlock: ((Throwable) -> T?) = {
            if (toastError) {
                it.message?.toast()
            }
            null
        },
        crossinline finallyBlock: (() -> Unit) = {},
        crossinline block: suspend CoroutineScope.() -> T
    ): Job {
        return viewModelScope.launch(context, start) {
            this@runOnScope.runWithStatus(errorBlock, finallyBlock) {
                block.invoke(this)
            }
        }
    }

    /**
     * 需要处理错误回调
     */
    inline fun <T> MutableLiveData<StatusData<T>>.runOnScopeWithError(
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        crossinline errorBlock: suspend ((Throwable) -> T?),
        crossinline block: suspend CoroutineScope.() -> T
    ): Job {
        return viewModelScope.launch(context, start) {
            this@runOnScopeWithError.runWithStatus({
                errorBlock.invoke(it)
            }) {
                block.invoke(this)
            }
        }
    }
}